﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SwinGame;

namespace SimpleSurvival.src
{
    //-----------------------------------------------//
    //CLASS - LinearPacketController.cs
    //-----------------------------------------------//
    //Controller to move objects in a linear direction
    public class LinearPacketController : ObjectController<IEntity>
    {
        //Needed because of some wierd floating point bug...
        const float HACK_SPEED = 0.1f;

        //Direction 
        Vector _velocity = new Vector { X = 0, Y = 0 };

        public override void GetInput(double dt)
        {
            //Moves the object in a linear fashion
            base.ControlledObject.Move(_velocity, dt * HACK_SPEED);
        }

        public LinearPacketController(Vector v){ _velocity = v; }
    }

    //-----------------------------------------------//
    //CLASS - SinePacketController.cs
    //-----------------------------------------------//
    //for the next iteration i would move these into one class
    //and use a strategy pattern to decide on the movement method
    //Not used at the moment, example of extending the object controller
    //Controller to move objects in a SinWave pattern.
    public class SinePacketController : ObjectController<IEntity>
    {
        const float HACK_SPEED = 0.1f;

        float _amp = 5.0f;
        float _period = 2.0f;
        float _time = 0;        //time in ticks 
        Vector _velocity = new Vector { X = 0, Y = 0 };

        public override void GetInput(double dt)
        {
            _time++;
            if (_amp == 0) { throw new Exception("zero sin amplitude"); }
            Vector os = new Vector 
            {    X = _amp * (float)Math.Cos(_period * _time),
                 Y = _amp * (float)Math.Sin(_period * _time) };
            if(os.X!=0||os.Y !=0)
            base.ControlledObject.Move(
                new Vector {    X = _velocity.X + os.X, 
                                Y = _velocity.Y + os.Y },
                                dt * HACK_SPEED);
        }

        public SinePacketController(Vector v, float amp, float period){
            _velocity = v;
            _amp = amp;
            _period = period; }
        
    }

    //-----------------------------------------------//
    //INTERFACE - IDamagePacket.cs
    //-----------------------------------------------//
    //Redundant?
    public interface IDamagePacket
    {
        bool IsDead { get; }
        void Update(double dt);
        int Damage { get; }
    }

    //-----------------------------------------------//
    //ENUM - DamagePacketType
    //-----------------------------------------------//
    //definitions//
    //Types of Damage Packets - Each has a different sprite
    public enum DamagePacketType
    {
        FIREBALL = 0,
    }

    //-----------------------------------------------//
    //CLASS - DamagePacket.cs
    //-----------------------------------------------//
    //Adds projectile functionality to an entity
    public class DamagePacket : Entity, IDamagePacket
    {
        IEntity _owner = null;

        int _damage = 0;
        
        bool _dead = false;
        double _age = 0;
        int _maxAge = 1000;

        public bool IsDead
        {
            get { return _dead; }
        }

        public int Damage
        {
            get { return _damage; }
        }

        public override void OnCollision(IEntity ent, double dt)    //protected
        {
            if (ent != _owner)                  //doesnt collide with caster
            {
                IUnit u = ent as IUnit;         //convert collider to IUnit
                if (u != null)
                {
                    ((IUnit)ent).IsHit(this, _owner);   //Tell collider its been hit
                    _dead = true;                       //destroy the projectile (this)
                }
            }
            base.OnCollision(ent, dt);    
            //removed base collision because it shouldnt react to collisions - buggy
        }

        //Updated from the IEntityList in map.
        public override void Update(double dt)
        {
            //bug where controller is updated twice otherwise class gets corrupted...
            //Update Controller - Thing thats moving the projectile
            Controller.GetInput(dt);// taken care of in entity class
            _age += dt*10;
            if (_age > _maxAge) { _dead = true; Map.RemoveEntity(this); }
            base.Update(dt); //some bug or something //fixed...
        }

        //Is added to Maps IEntity list at the Entity Initialisation.
        public DamagePacket(DamagePacketType t, ObjectController<IEntity> controller, int damage, IEntity owner, int life, Map m,EntityDrawer ed, EntityDefinitions defs)
            : base(Enum.GetName(typeof(DamagePacketType),t),owner.Position,m,ed,defs)
        {
            CanCollide = true;
            _maxAge = life;
            _owner = owner;
            _damage = damage;
            controller.LinkToObject(this);   
        }
    }
}
